package org.swift.mashup.wsdl;

import org.swift.commons.client.Call;

import com.eviware.soapui.impl.WsdlInterfaceFactory;
import com.eviware.soapui.impl.wsdl.WsdlInterface;
import com.eviware.soapui.impl.wsdl.WsdlOperation;
import com.eviware.soapui.impl.wsdl.WsdlProject;
import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlLoader;

public class WsdlWebService implements WebService<AxiomOperation> {

	private WsdlInterface[] wsdlInterfaces = null;

	private boolean showOptionalParamsInMessages = false;
	
	private final String url;

	@SuppressWarnings("unused")
	private static final String SECURE_PROTOCOL = "https";
	private static final String DEFAULT_PROTOCOL = "http";

	private String preferredProtocol = null;

	public WsdlWebService(String url) throws WsdlLoadException {
		this(url, false);
	}

	public WsdlWebService(String url, boolean showOptionalParamsInMessages,
			WsdlLoader wsdlLoader) throws WsdlLoadException {
		this.preferredProtocol = getPreferredProtocol(url);
		this.showOptionalParamsInMessages = showOptionalParamsInMessages;
		this.url = url;
		try {
			WsdlProject proj = new WsdlProject();
			wsdlInterfaces = WsdlInterfaceFactory.importWsdl(proj, url, false,
					wsdlLoader);
		} catch (Exception e) {
			throw new WsdlLoadException(url, e);
		}
	}

	public AxiomOperation getOperation(String operationName) {
		WsdlOperation op = this.wsdlInterfaces[0].getOperationByName(operationName);
		
		return new AxiomOperation(op.getName(),
				getEndpoint(this.preferredProtocol), op
						.createRequest(showOptionalParamsInMessages), op
						.createResponse(showOptionalParamsInMessages),
						op.getAction());
	}
	
	private String getPreferredProtocol (String url){
		int protocolEnd = url.indexOf(":");
		if (protocolEnd != -1){
			return url.substring(0, protocolEnd + 1);
		}
		return DEFAULT_PROTOCOL;
	}
	
	private String getEndpointStartingWith(String start, boolean allowNonMatch) {
		String lastEndpoint = null;
		for (String endpoint : this.wsdlInterfaces[0].getEndpoints()) {
			if (endpoint.startsWith(start))
				return endpoint;
			else if (allowNonMatch){
				lastEndpoint = endpoint;
			}
		}
		return lastEndpoint;
	}
	
	protected String getEndpoint (String preferredProtocol){
		return getEndpointStartingWith(preferredProtocol,true);
	}

	/**
	 * uses the SwiftUrlWsdlLoader by default
	 * 
	 * @param url
	 * @param showOptionalParamsInMessages
	 * @throws WsdlLoadException
	 */
	public WsdlWebService(String url, boolean showOptionalParamsInMessages)
			throws WsdlLoadException {
		this(url, showOptionalParamsInMessages, new SwiftUrlWsdlLoader(url));
	}

	public Call createCall(String operationName) throws WsdlLoadException {
		WsdlOperation op = this.wsdlInterfaces[0].getOperationByName(operationName);
		String sampleRequest = op.createRequest(true);
		return new OperationCall(url, operationName, sampleRequest);		
	}
}
